/**
 * Copyright 2018 orivil.com. All rights reserved.
 * Use of this source code is governed by a MIT-style
 * license that can be found at https://mit-license.org.
 */

package actions

import (
	"encoding/json"
	"gitee.com/tugoer/orivil/mux"
	"gitee.com/tugoer/orivil/trace"
	"gitee.com/tugoer/orivil/log"
	"gitee.com/tugoer/psy-testing/code/model"
	"gitee.com/tugoer/psy-testing/code/api/tags"
)

const (
	RouteAdminLogin = "admin/login"
	RouteAdminInfo = "admin/info"
)

var Admin = []*mux.Action{
	{
		Name: "Admin Info",
		Method:"GET",
		Route: RouteAdminInfo,
		Handler: func(ctx *mux.Context) {
			a := GetAdminFromSession(ctx)
			ctx.SendJson(a)
		},
		ApiDoc:&mux.ApiDoc{
			Tags:[]string{tags.Admin},
			Summary:"获得当前登陆的管理员信息",
			Responses:mux.Responses{
				"200":{
					Description:"success",
					Example:model.Admin{},
				},
			},
		},
	},
	{
		Name: "Admin Logout",
		Method:"GET",
		Route: "admin/logout",
		Handler: func(ctx *mux.Context) {
			DelAdminFromSession(ctx)
			ctx.Redirect("/admin/index")
		},
		ApiDoc:&mux.ApiDoc{
			Tags:[]string{tags.Admin},
			Summary:"退出登陆",
		},
	},
	{
		Name: "Admin Login",
		Method:"POST",
		Route: RouteAdminLogin,
		Params:mux.Parameters{
			{
				In:mux.Form,
				Schema:&loginAdmin{},
			},
		},
		Handler: func(ctx *mux.Context) {
			p := &loginAdmin{}
			ctx.WarnParse(p)
			a, err := model.AdminLogin(p.Name, p.Password)
			if err != nil {
				if err == model.ErrNotAllowedLogin {
					ctx.MsgWarning("该账号被禁止登陆", "")
				} else if err == model.ErrWrongUsername || err == model.ErrWrongPassword {
					ctx.MsgWarning("账号或密码错误", "")
				} else {
					ctx.ErrWarning(err)
				}
			} else {
				err = SetAdminToSession(ctx, a)
				ctx.ErrWarning(err)
				ctx.MsgSuccess("登陆成功", "")
			}
		},
		ApiDoc:&mux.ApiDoc{
			Tags:[]string{tags.Admin},
			Summary:"登陆管理员",
		},
	},

	{
		Name: "Admin Create Child",
		Method:"POST",
		Route: "admin/create/child",
		Params:mux.Parameters{
			{
				In:mux.Form,
				Schema:&model.Admin{},
				Ignore:[]string{
					"ID", "Parent", "CreatedAt",
				},
			},
		},
		Handler: func(ctx *mux.Context) {
			if parent := GetAdminFromSession(ctx); parent != nil && parent.Parent == 0 {
				p := &model.Admin{}
				ctx.WarnParse(p)
				err := model.AdminCreateChild(parent.ID, p)
				ctx.ErrWarning(err)
				ctx.MsgSuccess("创建成功", "")
			} else {
				ctx.MsgWarning("必须以超级管理员登陆", "")
			}
		},
		ApiDoc:&mux.ApiDoc{
			Tags:[]string{tags.Admin},
			Summary:"创建子管理员帐号",
			Description: "必须是超级管理员才能执行此操作",
		},
	},

	{
		Name: "Admin Get Children",
		Method:"GET",
		Route: "admin/children",
		Handler: func(ctx *mux.Context) {
			if parent := GetAdminFromSession(ctx); parent != nil && parent.Parent == 0 {
				as, err := model.GetChildren(parent.ID)
				if err != nil {
					ctx.ErrWarning(err)
				} else {
					ctx.SendJson(as)
				}
			} else {
				ctx.MsgWarning("必须以超级管理员登陆", "")
			}
		},
		ApiDoc:&mux.ApiDoc{
			Tags:[]string{tags.Admin},
			Summary:"获取所有子管理员信息",
			Description: "必须是超级管理员才能执行此操作",
			Responses:mux.Responses{
				"200":{
					Description:"success",
					Example:[]model.Admin{{}},
				},
			},
		},
	},

	{
		Name: "Admin Update Children",
		Method:"PUT",
		Route: "admin/children",
		Params:mux.Parameters{
			{
				In:mux.Form,
				Schema: &updateChild{},
			},
		},
		Handler: func(ctx *mux.Context) {
			if parent := GetAdminFromSession(ctx); parent != nil && parent.Parent == 0 {
				p := updateChild{}
				ctx.WarnParse(p)
				err := model.AdminUpdateChild(parent.ID, p.ChildName, p.Password, p.AllowedLogin)
				// TODO: ErrRecordNotFound? 子帐号不存在
				ctx.ErrWarning(err)
				ctx.MsgWarning("修改成功", "")
			} else {
				ctx.MsgWarning("必须以超级管理员登陆", "")
			}
		},
		ApiDoc:&mux.ApiDoc{
			Tags:[]string{tags.Admin},
			Summary:"修改子管理员信息",
			Description: "必须是超级管理员才能执行此操作",
		},
	},
}

type (
	getHashedData struct {
		Data string
	}
	loginAdmin struct {
		Name string `desc:"管理员账号" required:"管理员账号不能为空"`
		Password string `desc:"管理员密码" required:"密码不能为空"`
	}
	updateChild struct {
		ChildName string `desc:"所属的子帐号" required:"子帐号不能为空"`
		Password string
		AllowedLogin bool
	}
	updatePassword struct {
		VerificationCode string `desc:"邮箱收到的验证码" required:"邮箱验证码不能为空"`
		Password string `desc:"管理员密码" required:"密码不能为空"`
	}
	sendVerified struct {
		Name string `desc:"用户帐号，修改密码时使用"`
		Email string `desc:"用户邮箱，创建帐号时使用"`
	}
)

func GetAdminFromSession(ctx *mux.Context) *model.Admin {
	str := ctx.Session().Get("admin")
	if str == "" {
		return nil
	}
	a := &model.Admin{}
	err := json.Unmarshal([]byte(str), a)
	if err != nil {
		log.Emergency.Println(trace.Error(err))
		return nil
	} else {
		return a
	}
}

func DelAdminFromSession(ctx *mux.Context) {
	ctx.Session().Del("admin")
}

func SetAdminToSession(ctx *mux.Context, a *model.Admin) error {
	data, err := json.Marshal(a)
	if err != nil {
		return err
	}
	ctx.Session().Set("admin", string(data))
	return nil
}